
#pragma once

#include <WinDef.h>

#include <DXGI.h>
#include <D3D10_1.h>
#include <D3DX11.h>
#include <D3DX10math.h>

#include "Math\Matrix4x4.h"
#include "Math\Vector4.h"

class Matrix4x4;

class Quaternion
{
public:
	Quaternion();
    Quaternion(const Vector4& vector);
    Quaternion(FLOAT a, FLOAT b, FLOAT c, FLOAT d);
    ~Quaternion();

    Quaternion(const Quaternion& other);
    Quaternion& operator = (const Quaternion& other);
	
	// Static constructors.
	//------------------------------------------------
    static Quaternion CreateRotation(FLOAT x, FLOAT y, FLOAT z, FLOAT angle);
    static Quaternion CreateRotation(const Vector4& axis, FLOAT angle);

	// Getters & Setters.
	//-----------------------------------------------
    Vector4 GetVector() const;
    FLOAT GetScalar() const;

	// Operations.
	//-----------------------------------------------
	Quaternion Normalize() const;
    Quaternion Interpolate(const Quaternion& other, FLOAT u) const;

	// Operators.
	//-----------------------------------------------
    Quaternion Add(const Quaternion& other) const;
    Quaternion operator + (const Quaternion& other) const;
	Quaternion& operator += (const Quaternion& other);

    Quaternion Sub(const Quaternion& other) const;
    Quaternion operator - (const Quaternion& other) const;
	Quaternion& operator -= (const Quaternion& other);

	Quaternion Mul(FLOAT factor) const;

    FLOAT Dot(const Quaternion& other) const;

	// Casting operators.
	//-----------------------------------------------
    operator Matrix4x4() const;
	operator D3DXMATRIX() const;

private:
	// Attributes.
	//-----------------------------------------------
    Vector4 m_quaternion;
};

Quaternion operator * (const Quaternion& quaternion, FLOAT factor);
Quaternion operator * (FLOAT factor, const Quaternion& quaternion);